package com.mbc.web.common.client.ui.control;

import java.util.ArrayList;
import java.util.Date;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment;
import com.google.gwt.user.datepicker.client.DateBox;

public class GridView extends FlexTable implements ContextMenuHandler {

	public static final String NO_ORDER = "";
	public static final String ASCENDING = "asc";
	public static final String DESCENDING = "desc";
	
	private Element trHead;
	private Element tfoot;
	private ArrayList<GridColumn> gridColumns;
	private FlexCellFormatter cellFormatter;
	private RowFormatter rowFormatter;
	private ArrayList<Integer> focusables;
	private int selectedRowIndex;
	private int selectedColumnIndex;
	private boolean isRightClick = false;
	private boolean enabled = true;
	//public ContextMenuStrip contextMenuStrip;
	public boolean allowUserToAddRow = true;
	private ClickHandler clickHandler;
	private byte sortedColumnsCount = 0;
	
	public int getColumnCount()
	{
		return gridColumns.size();
	}
	
	public int getSelectedRowIndex()
	{
		return selectedRowIndex;
	}
	
	public int getSelectedColumnIndex()
	{
		return selectedRowIndex;
	}
	
	public void setAttribute(int row, int column, String name, String value)
	{
		cellFormatter.getElement(row, column).setAttribute(name, value);
	}
	
	public String getAttribute(int row, int column, String name)
	{
		return cellFormatter.getElement(row, column).getAttribute(name);
	}
	
	public void removeAttribute(int row, int column, String name)
	{
		cellFormatter.getElement(row, column).removeAttribute(name);
	}
	
	@Override
	public void onBrowserEvent(Event event) {
		super.onBrowserEvent(event);
		isRightClick = false;
		if(event.getTypeInt() == 262144)
		{
			isRightClick = true;
			NativeEvent l_NativeEvent = Document.get().createClickEvent(-1, event.getScreenX(), event.getScreenY(), event.getClientX(), event.getClientY(), false, false, false, false);
			DOM.eventGetTarget(event).dispatchEvent(l_NativeEvent);
		}
	}
	
	public void setColumnVisible(int column, boolean visible)
	{
		NodeList<Element> l_ths = this.getElement().getElementsByTagName("th");
		if(visible)
			l_ths.getItem(column).setAttribute("style", "");
		else
			l_ths.getItem(column).setAttribute("style", "display:none;");
		int l_rowCount = getRowCount();
		CellFormatter l_cf = getCellFormatter();
		for (int i = 0; i < l_rowCount; i++) {
			if(visible)
				l_cf.getElement(i, column).setAttribute("style", "");
			else
				l_cf.getElement(i, column).setAttribute("style", "display:none;");
		}
	}
	
	public void setEnabled(boolean enabled)
	{
		this.enabled = enabled;
		int l_rowCount = getRowCount();
		for (int i = 0; i < l_rowCount; i++) {
			int l_columnCount = getColumnCount();
			for (int j = 0; j < l_columnCount; j++) {
				switch (gridColumns.get(j).columnType) {
				case GridColumn.column_TextBox:
					((TextBox)this.getWidget(i, j)).setEnabled(enabled);
					break;
				case GridColumn.column_ComboBox:
					((ListBox)this.getWidget(i, j)).setEnabled(enabled);
					break;
				case GridColumn.column_CheckBox:
					((CheckBox)this.getWidget(i, j)).setEnabled(enabled);
					break;
				case GridColumn.column_Button:
					((Button)this.getWidget(i, j)).setEnabled(enabled);
					break;
				case GridColumn.column_image:
					((Image)this.getWidget(i, j)).setVisible(enabled);
					break;
				case GridColumn.column_default:
				case GridColumn.column_auto_number:
				case GridColumn.column_label_column:
					break;
				case GridColumn.column_lookup_column:
					((TextBox)((HorizontalPanel)this.getWidget(i, j)).getWidget(0)).setEnabled(enabled);
					((Button)((HorizontalPanel)this.getWidget(i, j)).getWidget(1)).setEnabled(enabled);
					break;
				case GridColumn.column_radio_button:
					((RadioButton)this.getWidget(i, j)).setEnabled(enabled);
					break;
				}
			}
		}
	}
	
	public GridView()
	{
		DateTimeFormat l_dateTimeFmt = DateTimeFormat.getFormat("HHmmssSSS");
		this.getElement().setId(l_dateTimeFmt.format(new Date()));
		this.addDomHandler(this, ContextMenuEvent.getType());
		gridColumns = new ArrayList<GridColumn>();
		cellFormatter = this.getFlexCellFormatter();
		rowFormatter = this.getRowFormatter();
		focusables = new ArrayList<Integer>();
		
		Element l_Grid = this.getElement();
		Element l_thead = DOM.createTHead();
		tfoot = DOM.createElement("tfoot");
		trHead = DOM.createTR();
		l_Grid.insertFirst(l_thead);
		l_Grid.appendChild(tfoot);
		l_thead.appendChild(trHead);
		clickHandler = new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				Cell l_cell = GridView.this.getCellForEvent(event);
				if(l_cell != null)
				{
					selectedRowIndex = l_cell.getRowIndex();
					selectedColumnIndex = l_cell.getCellIndex();
					if(isRightClick)
						if(enabled)
						{
//							if(contextMenuStrip != null)
//							{
//								contextMenuStrip.setPopupPosition(event.getClientX(), event.getClientY());
//								contextMenuStrip.show();
//							}
							
						}
				}
			}
		};
		this.addClickHandler(clickHandler);
	}
	
	public String getSortedColumn() {
		return getJSSortedColumn(this.getElement().getId());
	}
	
	private native String getJSSortedColumn(String id)/*-{
		return $wnd.$("#" + id + " thead th[sort=true]").text().trim();
	}-*/;

	public void setSortedColumn(int col, String order) {
		renderColumnHeaderSortable(this.getElement().getId());
		setJSSortedColumn(this.getElement().getId(), col + 1, order);
	}
	
	private native void setJSSortedColumn(String id, int col, String order)/*-{
		if(order === 'asc')
			$wnd.$("#" + id + " thead tr th:nth-child(" + col + ") i").attr("class","fa fa-long-arrow-up");
		else
			$wnd.$("#" + id + " thead tr th:nth-child(" + col + ") i").attr("class","fa fa-long-arrow-down");
		$wnd.$("#" + id + " thead tr th:nth-child(" + col + ")").attr("sort",true).attr("order",order);
	}-*/;

	public String getSortedOrder() {
		return getJSSortedOrder(this.getElement().getId());
	}
	
	private native String getJSSortedOrder(String id)/*-{
		return $wnd.$("#" + id + " thead th[sort=true]").attr("order");
	}-*/;

	public void addColumn(GridColumn column)
	{
		switch (column.columnType) {
		case GridColumn.column_TextBox:
		case GridColumn.column_ComboBox:
		case GridColumn.column_lookup_column:
			focusables.add(gridColumns.size());
		break;
		}
		column.index = gridColumns.size();
		gridColumns.add(column);
		Element l_th = DOM.createTH();
		if(column.isSortable()){
			final int l_finalIndex = column.index;
			if(sortedColumnsCount == 0){
				l_th.setAttribute("order", String.valueOf(ASCENDING));
				l_th.setAttribute("sort", "true");
				l_th.setInnerHTML(column.header + " <i class='fa fa-long-arrow-up'></i>");
				sortedColumnsCount++;
			}
			else{
				l_th.setAttribute("order", String.valueOf(NO_ORDER));
				l_th.setAttribute("sort", "false");
				l_th.setInnerHTML(column.header + " <i class='fa fa-arrows-v'></i>");
			}
			DOM.sinkEvents((com.google.gwt.user.client.Element)l_th, Event.ONCLICK);
			DOM.setEventListener((com.google.gwt.user.client.Element)l_th, new EventListener() {
				
				@Override
				public void onBrowserEvent(Event event) {
					if(event.getTypeInt() == Event.ONCLICK){
						renderColumnHeaderSortable(GridView.this.getElement().getId());
						Element l_ele = Element.as(event.getEventTarget());
						if(l_ele.getNodeName().equals("I")){
							l_ele = l_ele.getParentElement();
						}
						if(l_ele.getAttribute("order").equals(DESCENDING) ||
								l_ele.getAttribute("order").equals(NO_ORDER)){
							l_ele.setAttribute("order", ASCENDING);
							l_ele.getElementsByTagName("i").getItem(0).setAttribute("class", "fa fa-long-arrow-up");
						}
						else{
							l_ele.setAttribute("order", DESCENDING);
							l_ele.getElementsByTagName("i").getItem(0).setAttribute("class", "fa fa-long-arrow-down");
						}
						l_ele.setAttribute("sort", "true");
						gridColumns.get(l_finalIndex).getHeaderClickhandler().onClick(null);
					}
				}
			});
		}
		else
			l_th.setInnerText(column.header);
		if(column.width != null && !column.equals(""))
			l_th.setAttribute("width", column.width);
		trHead.appendChild(l_th);
	}
	
	private native void renderColumnHeaderSortable(String id)/*-{
		$wnd.$("#" + id + ">thead i").attr("class","fa fa-arrows-v");
		$wnd.$("#" + id + ">thead th[order]").attr("sort","false");
	}-*/;
	
	public void cellFocus(int row , int column)
	{
		GridColumn l_column = gridColumns.get(column);
		switch (l_column.columnType) {
		case GridColumn.column_TextBox:
			((TextBox)GridView.this.getWidget(row, column)).setFocus(true);
			break;
		case GridColumn.column_ComboBox:
			((ListBox)GridView.this.getWidget(row, column)).setFocus(true);
			break;
		case GridColumn.column_lookup_column:
			((TextBox)((HorizontalPanel)this.getWidget(row, column)).getWidget(0)).setFocus(true);
			break;
		}
	}
	
	private void prepareIndex()
	{
		com.google.gwt.user.client.Element l_Body = DOM.getChild(this.getElement(), 2);
		int l_rowCount = l_Body.getChildCount();
		for (int i = 0; i < l_rowCount; i++) {
			Element l_row = DOM.getChild(l_Body, i);
			l_row.setAttribute("i", String.valueOf(i));
			int l_colCount = gridColumns.size();
			for (int j = 0; j < l_colCount; j++) {
				if(gridColumns.get(j).columnType == GridColumn.column_auto_number)
				{
					this.setText(i, j, String.valueOf(i + 1));
				}
			}
		}
	}
	
	public GridViewCellPosition getCellPosition(int row, int column)
	{
		GridViewCellPosition l_position = new GridViewCellPosition();
		switch (gridColumns.get(column).columnType) {
		case GridColumn.column_TextBox:
			TextBox l_txt = (TextBox)this.getWidget(row, column);
			l_position.left = l_txt.getAbsoluteLeft();
			l_position.top = l_txt.getAbsoluteTop();
			break;
		case GridColumn.column_ComboBox:
			ListBox l_lst = (ListBox)this.getWidget(row, column);
			l_position.left = l_lst.getAbsoluteLeft();
			l_position.top = l_lst.getAbsoluteTop();
			break;
		case GridColumn.column_lookup_column:
			TextBox l_txtLookup = (TextBox)((HorizontalPanel)this.getWidget(row, column)).getWidget(0);
			l_position.left = l_txtLookup.getAbsoluteLeft();
			l_position.top = l_txtLookup.getAbsoluteTop();
			break;
		}
		return l_position;
	}
	
	public void addRow()
	{
		String[] l_values = new String[gridColumns.size()];
		for (int i = 0; i < l_values.length; i++) {
			l_values[i] = "";
		}
		addRow(l_values);
	}
	
	public void addRow(String[] values)
	{
		int l_rowIndex = this.getRowCount();
		this.insertRow(l_rowIndex);
		KeyDownHandler l_KeyDownHandler = new KeyDownHandler() {
			
			@Override
			public void onKeyDown(KeyDownEvent event) {
				int l_nativeCode = event.getNativeKeyCode();
				if(l_nativeCode == KeyCodes.KEY_ENTER) // enter
				{
					if(GridView.this.selectedColumnIndex == focusables.get(focusables.size() - 1))
					{
						if(selectedRowIndex == GridView.this.getRowCount() - 1)
						{
							String[] l_values = new String[gridColumns.size()];
							for (int j = 0; j < l_values.length; j++) {
								l_values[j] = "";
							}
							if(allowUserToAddRow)
								addRow(l_values);
						}
						else
						{
							cellFocus(selectedRowIndex + 1, focusables.get(0));
						}
					}
					else
					{
						for (int j = 0; j < focusables.size(); j++) {
							if(GridView.this.selectedColumnIndex == focusables.get(j))
							{
								cellFocus(selectedRowIndex, focusables.get(j + 1));
								break;
							}
						}
					}
				}
				else if(l_nativeCode == KeyCodes.KEY_ESCAPE) // escape
				{
					setValue(selectedRowIndex, selectedColumnIndex, getAttribute(selectedRowIndex, selectedColumnIndex, "p_value"));
				}
				else if(l_nativeCode == KeyCodes.KEY_LEFT || l_nativeCode == KeyCodes.KEY_RIGHT || l_nativeCode == KeyCodes.KEY_UP || l_nativeCode == KeyCodes.KEY_DOWN)
				{
					if(gridColumns.get(selectedColumnIndex).columnType != GridColumn.column_ComboBox)
					{
						if(l_nativeCode == KeyCodes.KEY_LEFT)
						{
							int l_size = focusables.size();
							for (int i = 0; i < l_size; i++) {
								if(focusables.get(i) == selectedColumnIndex)
								{
									if(i != 0)
										cellFocus(selectedRowIndex, focusables.get(i - 1));
									break;
								}
							}
						}
						else if(l_nativeCode == KeyCodes.KEY_UP)
						{
							if(selectedRowIndex != 0)
							{
								cellFocus(selectedRowIndex - 1, selectedColumnIndex);
							}
						}
						else if(l_nativeCode == KeyCodes.KEY_RIGHT)
						{
							int l_size = focusables.size();
							for (int i = 0; i < l_size; i++) {
								if(focusables.get(i) == selectedColumnIndex)
								{
									if(i != l_size - 1)
									{
										cellFocus(selectedRowIndex, focusables.get(i + 1));
									}
									break;
								}
							}
						}
						else if(l_nativeCode == KeyCodes.KEY_DOWN)
						{
							if(selectedRowIndex != getRowCount() - 1)
							{
								cellFocus(selectedRowIndex + 1, selectedColumnIndex);
							}
						}
					}
				}
			}
		};
		BlurHandler l_BlurHandler = new BlurHandler() {
			
			@Override
			public void onBlur(BlurEvent event) {
				setAttribute(selectedRowIndex, selectedColumnIndex, "p_value", getValue(selectedRowIndex, selectedColumnIndex));
			}
		};
		for (int i = 0; i < values.length ; i++) {
			GridColumn l_column = gridColumns.get(i);
			final int l_colIndex = i;
		
			FocusHandler l_focushandler = new FocusHandler() {
				
				@Override
				public void onFocus(FocusEvent event) {
					Widget l_widget = (Widget)event.getSource();
					if(gridColumns.get(l_colIndex).columnType != GridColumn.column_lookup_column)
						selectedRowIndex = Integer.parseInt(l_widget.getElement().getParentElement().getParentElement().getAttribute("i"));
					else
						selectedRowIndex = Integer.parseInt(l_widget.getParent().getElement().getParentElement().getParentElement().getAttribute("i"));
						
					selectedColumnIndex = l_colIndex;
				}
			};
			switch (l_column.columnType) {
			case GridColumn.column_default:
				this.setText(l_rowIndex, i, values[i]);
				break;
			case GridColumn.column_TextBox:
				GridTextBoxColumn l_txtColumn = (GridTextBoxColumn)l_column;
				TextBox l_txt = new TextBox();
				l_txt.setText(values[i]);
				l_txt.setWidth(l_column.width);
				l_txt.setEnabled(enabled);
				l_txt.setStyleName(l_txtColumn.styleName);
				l_txt.addFocusHandler(l_focushandler);
				l_txt.addBlurHandler(l_BlurHandler);
				l_txt.addKeyDownHandler(l_KeyDownHandler);
				if(l_txtColumn.keyPressHandler != null)
					l_txt.addKeyPressHandler(l_txtColumn.keyPressHandler);
				if(l_txtColumn.keyDwonHandler!=null)
					l_txt.addKeyDownHandler(l_txtColumn.keyDwonHandler);
				if(l_txtColumn.blurHandler != null)
					l_txt.addBlurHandler(l_txtColumn.blurHandler);
				if(l_txtColumn.focusHandler != null)
					l_txt.addFocusHandler(l_txtColumn.focusHandler);
				if(l_txtColumn.changeHandler != null)
					l_txt.addChangeHandler(l_txtColumn.changeHandler);
				if(l_txtColumn.horizontalAlignment != null)
				{
					if(l_txtColumn.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_LEFT))
						l_txt.setAlignment(TextAlignment.LEFT);
					else if(l_txtColumn.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_RIGHT))
						l_txt.setAlignment(TextAlignment.RIGHT);
					else if(l_txtColumn.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_CENTER))
						l_txt.setAlignment(TextAlignment.CENTER);
				}
				this.setWidget(l_rowIndex, i, l_txt);
				break;
			case GridColumn.column_datebox:
				GridDateBoxColumn l_dateColumn = (GridDateBoxColumn)l_column;
				DateBox l_dtp = new DateBox();
				DateTimeFormat l_format=DateTimeFormat.getFormat("dd/MM/yyyy");
				l_dtp.setFormat(new DateBox.DefaultFormat(l_format));
				if(values[i].equals(""))
				{
					Date l_date = new Date();
					l_dtp.setValue(l_date);
				}
				else
					l_dtp.getTextBox().setText(values[i]);
				l_dtp.setWidth(l_column.width);
				l_dtp.setEnabled(enabled);
				TextBox l_txtDate = l_dtp.getTextBox();
				l_txtDate.addFocusHandler(l_focushandler);
				l_txtDate.addBlurHandler(l_BlurHandler);
				l_txtDate.addKeyDownHandler(l_KeyDownHandler);
				if(l_dateColumn.keyPressHandler != null)
					l_txtDate.addKeyPressHandler(l_dateColumn.keyPressHandler);
				if(l_dateColumn.keyDwonHandler!=null)
					l_txtDate.addKeyDownHandler(l_dateColumn.keyDwonHandler);
				if(l_dateColumn.blurHandler != null)
					l_txtDate.addBlurHandler(l_dateColumn.blurHandler);
				if(l_dateColumn.focusHandler != null)
					l_txtDate.addFocusHandler(l_dateColumn.focusHandler);
				if(l_dateColumn.changeHandler != null)
					l_txtDate.addChangeHandler(l_dateColumn.changeHandler);
				if(l_dateColumn.horizontalAlignment != null)
				{
					if(l_dateColumn.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_LEFT))
						l_txtDate.setAlignment(TextAlignment.LEFT);
					else if(l_dateColumn.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_RIGHT))
						l_txtDate.setAlignment(TextAlignment.RIGHT);
					else if(l_dateColumn.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_CENTER))
						l_txtDate.setAlignment(TextAlignment.CENTER);
				}
				this.setWidget(l_rowIndex, i, l_dtp);
				break;
			case GridColumn.column_ComboBox:
				GridComboBoxColumn l_ComboColumn = (GridComboBoxColumn)l_column;
				ListBox l_lst = new ListBox();
				
				l_lst.setWidth(l_column.width);
				l_lst.setEnabled(enabled);
				l_lst.setStyleName(l_ComboColumn.styleName);
				l_lst.addFocusHandler(l_focushandler);
				l_lst.addKeyDownHandler(l_KeyDownHandler);
				l_lst.addBlurHandler(l_BlurHandler);
				if(l_ComboColumn.changeHandler != null)
					l_lst.addChangeHandler(l_ComboColumn.changeHandler);
				if(l_ComboColumn.focusHandler != null)
					l_lst.addFocusHandler(l_ComboColumn.focusHandler);
				GridComboBoxColumn l_ComboCol = (GridComboBoxColumn)l_column;
				if(l_ComboCol.dataSource != null)
				{
					int l_size = l_ComboCol.dataSource.size();
					for (int j = 0; j < l_size; j++) {
						l_lst.addItem(l_ComboCol.dataSource.get(j)[0], l_ComboCol.dataSource.get(j)[1]);
						if(l_lst.getValue(j).equals(values[i]))
							l_lst.setSelectedIndex(j);
					}
				}
				this.setWidget(l_rowIndex, i, l_lst);
				break;
			case GridColumn.column_CheckBox:
				GridCheckBoxColumn l_chkCol = (GridCheckBoxColumn)l_column;
				CheckBox l_chk = new CheckBox();
				l_chk.addClickHandler(clickHandler);
				if(l_chkCol.valueChangeHandler != null)
					l_chk.addValueChangeHandler(l_chkCol.valueChangeHandler);
				l_chk.setEnabled(enabled);
				l_chk.setValue(values[i].equals("true"));
				this.setWidget(l_rowIndex, i, l_chk);
				
				break;
			case GridColumn.column_radio_button:
				GridRadioButtonColumn l_rdoCol = (GridRadioButtonColumn)l_column;
				RadioButton l_rdo = new RadioButton(l_rdoCol.name);
				l_rdo.addClickHandler(clickHandler);
				if(l_rdoCol.valueChangeHandler != null)
					l_rdo.addValueChangeHandler(l_rdoCol.valueChangeHandler);
				l_rdo.setEnabled(enabled);
				l_rdo.setValue(values[i].equals("true"));
				this.setWidget(l_rowIndex, i, l_rdo);
				break;
			case GridColumn.column_Button:
				GridButtonColumn l_BtnCol = (GridButtonColumn)l_column;
				Button l_btn = new Button();
				l_btn.setEnabled(enabled);
				l_btn.setStyleName(l_BtnCol.styleName);
				l_btn.addClickHandler(clickHandler);
				l_btn.addFocusHandler(l_focushandler);
				if(l_BtnCol.html.equals(""))
					l_btn.setText(l_BtnCol.text);
				else
					l_btn.setHTML(l_BtnCol.html);
				l_btn.setWidth(l_column.width);
				if(l_BtnCol.clickHandler != null)
					l_btn.addClickHandler(l_BtnCol.clickHandler);
				this.setWidget(l_rowIndex, l_colIndex, l_btn);
				break;
			case GridColumn.column_image:
				GridImageColumn l_ImgCol = (GridImageColumn)l_column;
				Image l_Image = new Image(l_ImgCol.url);
				l_Image.setVisible(enabled);
				l_Image.addClickHandler(clickHandler);
				if(l_ImgCol.clickHandler != null)
				{
					l_Image.addClickHandler(l_ImgCol.clickHandler);
				}
				this.setWidget(l_rowIndex, l_colIndex, l_Image);
				break;
			case GridColumn.column_label_column:
				GridLabelColumn l_lblCol = (GridLabelColumn)l_column;
				Label l_lbl = new Label();
				l_lbl.setText(values[i]);
				l_lbl.addClickHandler(clickHandler);
				if(l_lblCol.clickHandler != null)
					l_lbl.addClickHandler(l_lblCol.clickHandler);
				if(!l_lblCol.styleName.equals(""))
					l_lbl.setStyleName(l_lblCol.styleName);
				l_lbl.setHorizontalAlignment(l_lblCol.horizontalAlignment);
				this.setWidget(l_rowIndex, l_colIndex, l_lbl);
				break;
			case GridColumn.column_lookup_column:
//				GridLookupColumn l_lookupCol = (GridLookupColumn)l_column;
//				TextBox l_lookupTxtBox = new TextBox();
//				l_lookupTxtBox.setText(values[i]);
//				l_lookupTxtBox.setWidth("100%");
//				l_lookupTxtBox.setEnabled(enabled);
//				l_lookupTxtBox.addFocusHandler(l_focushandler);
//				l_lookupTxtBox.addKeyDownHandler(l_KeyDownHandler);
//				l_lookupTxtBox.addBlurHandler(l_BlurHandler);
//				if(l_lookupCol.keyDownHandler != null)
//					l_lookupTxtBox.addKeyDownHandler(l_lookupCol.keyDownHandler);
//				if(l_lookupCol.keyPressHandler != null)
//					l_lookupTxtBox.addKeyPressHandler(l_lookupCol.keyPressHandler);
//				if(l_lookupCol.blurHandler != null)
//					l_lookupTxtBox.addBlurHandler(l_lookupCol.blurHandler);
//				if(l_lookupCol.focusHandler != null)
//					l_lookupTxtBox.addFocusHandler(l_lookupCol.focusHandler);
//				if(l_lookupCol.changeHandler != null)
//					l_lookupTxtBox.addChangeHandler(l_lookupCol.changeHandler);
//				if(l_lookupCol.horizontalAlignment != null)
//				{
//					if(l_lookupCol.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_LEFT))
//						l_lookupTxtBox.setAlignment(TextAlignment.LEFT);
//					else if(l_lookupCol.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_RIGHT))
//						l_lookupTxtBox.setAlignment(TextAlignment.RIGHT);
//					else if(l_lookupCol.horizontalAlignment.equals(HasHorizontalAlignment.ALIGN_CENTER))
//						l_lookupTxtBox.setAlignment(TextAlignment.CENTER);
//				}
//				if(l_column.verticalAlignment != null)
//					cellFormatter.setVerticalAlignment(l_rowIndex, i, l_column.verticalAlignment);
//				ImageButton l_lookupBtn = new ImageButton();
//				l_lookupBtn.setResource("img/icons/bs/ic_zoom.png");
//				l_lookupBtn.addFocusHandler(l_focushandler);
//				l_lookupBtn.setEnabled(enabled);
//				l_lookupBtn.addClickHandler(clickHandler);
//				if(l_lookupCol.clickHandler != null)
//					l_lookupBtn.addClickHandler(l_lookupCol.clickHandler);
//				
//				HorizontalPanel l_hp = new HorizontalPanel();
//				l_hp.setStyleName("");
//				l_hp.setWidth(l_column.width);
//				l_hp.add(l_lookupTxtBox);
//				l_hp.add(l_lookupBtn);
//				l_hp.setCellWidth(l_lookupBtn, "30px");
//				this.setWidget(l_rowIndex, l_colIndex, l_hp);
				break;
			}
			
			if(l_column.horizontalAlignment != null)
				cellFormatter.setHorizontalAlignment(l_rowIndex, i, l_column.horizontalAlignment);
			if(l_column.verticalAlignment != null)
				cellFormatter.setVerticalAlignment(l_rowIndex, i, l_column.verticalAlignment);
			if(l_column.height != null && !l_column.height.equals(""))
				cellFormatter.setHeight(l_rowIndex, i, l_column.height);
			if(!l_column.width.equals(""))
				cellFormatter.setWidth(l_rowIndex, l_colIndex, l_column.width);
			setAttribute(l_rowIndex, l_colIndex, "p_value", values[i]);
		}
		prepareIndex();
		if(focusables.size()>0){
			cellFocus(l_rowIndex,focusables.get(0));
		}
	}
	
	public void addFooterRow(){
		String[] l_values = new String[gridColumns.size()];
		for (int i = 0; i < l_values.length; i++) {
			l_values[i] = "";
		}
		addFooterRow(l_values);
	}
	
	public void addFooterRow(String[] values){
		if(values.length == gridColumns.size()){
			Element l_tr = DOM.createElement("tr");
			for (int i = 0; i < values.length; i++) {
				Element l_td = DOM.createElement("td");
				l_td.setInnerText(values[i]);
				
				if(gridColumns.get(i).horizontalAlignment != null){
					if(gridColumns.get(i).horizontalAlignment == HasHorizontalAlignment.ALIGN_LEFT){
						l_td.setAttribute("align", "left");
					} else if(gridColumns.get(i).horizontalAlignment == HasHorizontalAlignment.ALIGN_RIGHT){
						l_td.setAttribute("align", "right");
					} else if(gridColumns.get(i).horizontalAlignment == HasHorizontalAlignment.ALIGN_CENTER){
						l_td.setAttribute("align", "center");
					}
				}
				
				l_tr.appendChild(l_td);
			}	
			tfoot.appendChild(l_tr);
		}
	}
	
	public void setFooterValue(int row, int column, String text){
		if(row < tfoot.getChildCount()){
			if(column < gridColumns.size()){
				Element l_td = tfoot.getElementsByTagName("tr").getItem(row).getElementsByTagName("td").getItem(column);
				if(gridColumns.get(column).horizontalAlignment != null){
					if(gridColumns.get(column).horizontalAlignment == HasHorizontalAlignment.ALIGN_LEFT){
						l_td.setAttribute("align", "left");
					} else if(gridColumns.get(column).horizontalAlignment == HasHorizontalAlignment.ALIGN_RIGHT){
						l_td.setAttribute("align", "right");
					} else if(gridColumns.get(column).horizontalAlignment == HasHorizontalAlignment.ALIGN_CENTER){
						l_td.setAttribute("align", "center");
					}
				}
				l_td.setInnerText(text);
			}
		}
	}
	
	public void removeRow_(int row)
	{
		this.removeRow(row);
		prepareIndex();
	}
	
	public void addRowStyle(int row, String styleName){
		rowFormatter.addStyleName(row, styleName);
	}
	
	public void removeRowStyle(int row, String styleName){
		rowFormatter.removeStyleName(row, styleName);
	}
	
	public void addCellStyle(int row, int column, String styleName){
		cellFormatter.addStyleName(row, column, styleName);
	}
	
	public void setCellEnabled(int row, int column, boolean enabled)
	{
		switch (gridColumns.get(column).columnType) {
		case GridColumn.column_default:
		case GridColumn.column_auto_number:
		case GridColumn.column_image:
		case GridColumn.column_label_column:
			break;
		case GridColumn.column_TextBox:
			((TextBox)this.getWidget(row, column)).setEnabled(enabled);
			break;
		case GridColumn.column_datebox:
			((DateBox)this.getWidget(row, column)).setEnabled(enabled);
			break;
		case GridColumn.column_ComboBox:
			((ListBox)this.getWidget(row, column)).setEnabled(enabled);
			break;
		case GridColumn.column_CheckBox:
			((CheckBox)this.getWidget(row, column)).setEnabled(enabled);
			break;
		case GridColumn.column_radio_button:
			((RadioButton)this.getWidget(row, column)).setEnabled(enabled);
			break;
		case GridColumn.column_Button:
			((Button)this.getWidget(row, column)).setEnabled(enabled);
			break;
		case GridColumn.column_lookup_column:
			((TextBox)((HorizontalPanel)this.getWidget(row, column)).getWidget(0)).setEnabled(enabled);
			((Button)((HorizontalPanel)this.getWidget(row, column)).getWidget(1)).setEnabled(enabled);
			break;
		}
	}
	
	public String getValue(int row, int column)
	{
		switch (gridColumns.get(column).columnType) {
		case GridColumn.column_default:
		case GridColumn.column_auto_number:
			return this.getText(row, column);
		case GridColumn.column_TextBox:
			return ((TextBox)this.getWidget(row, column)).getText();
		case GridColumn.column_datebox:
			return ((DateBox)this.getWidget(row, column)).getTextBox().getText();
		case GridColumn.column_ComboBox:
			ListBox l_lst = (ListBox)this.getWidget(row, column);
			if(l_lst.getItemCount() == 0)
				return "";
			return l_lst.getValue(l_lst.getSelectedIndex());
		case GridColumn.column_CheckBox:
			return String.valueOf(((CheckBox)this.getWidget(row, column)).getValue());
		case GridColumn.column_radio_button:
			return String.valueOf(((RadioButton)this.getWidget(row, column)).getValue());
		case GridColumn.column_Button:
		case GridColumn.column_image:
			return "";
		case GridColumn.column_label_column:
			return ((Label)this.getWidget(row, column)).getText();
		case GridColumn.column_lookup_column:
			return ((TextBox)((HorizontalPanel)this.getWidget(row, column)).getWidget(0)).getText();
		}
		return "";
	}
	
	public String[] getValues(int row)
	{
		String[] l_values = new String[gridColumns.size()];
		for (int i = 0; i < l_values.length; i++) {
			switch (gridColumns.get(i).columnType) {
			case GridColumn.column_default:
			case GridColumn.column_auto_number:
				l_values[i] = this.getText(row, i);
				break;
			case GridColumn.column_TextBox:
				l_values[i] = ((TextBox)this.getWidget(row, i)).getText();
				break;
			case GridColumn.column_datebox:
				l_values[i] = ((DateBox)this.getWidget(row, i)).getTextBox().getText();
				break;
			case GridColumn.column_ComboBox:
				ListBox l_lst = (ListBox)this.getWidget(row, i);
				if(l_lst.getItemCount() == 0)
					l_values[i] = "";
				else
					l_values[i] = l_lst.getValue(l_lst.getSelectedIndex());
				break;
			case GridColumn.column_CheckBox:
				l_values[i] = String.valueOf(((CheckBox)this.getWidget(row, i)).getValue());
				break;
			case GridColumn.column_radio_button:
				l_values[i] = String.valueOf(((RadioButton)this.getWidget(row, i)).getValue());
				break;
			case GridColumn.column_Button:
			case GridColumn.column_image:
				l_values[i] = "";
				break;
			case GridColumn.column_label_column:
				l_values[i] = ((Label)this.getWidget(row, i)).getText();
				break;
			case GridColumn.column_lookup_column:
				l_values[i] = ((TextBox)((HorizontalPanel)this.getWidget(row, i)).getWidget(0)).getText();
				break;
			}
		}
		return l_values;
	}
	
	public void addValue(int row, int column, String item, String value)
	{
		if(gridColumns.get(column).columnType == GridColumn.column_ComboBox)
			((ListBox)getWidget(row, column)).addItem(item, value);
	}
	
	public void setValue(int row, int column, String text)
	{
		switch (gridColumns.get(column).columnType) {
		case GridColumn.column_default:
			this.setText(row, column, text);
			break;
		case GridColumn.column_TextBox:
		case GridColumn.column_datebox:
			((TextBox)this.getWidget(row, column)).setText(text);
			break;
		case GridColumn.column_ComboBox:
			ListBox l_lst = (ListBox)this.getWidget(row, column);
			for (int i = 0; i < l_lst.getItemCount(); i++) {
				if(text.equals(l_lst.getValue(i)))
				{
					l_lst.setSelectedIndex(i);
					break;
				}
			}
			break;
		case GridColumn.column_CheckBox:
			((CheckBox)this.getWidget(row, column)).setValue(text.equals("true"), true);
			break;
		case GridColumn.column_radio_button:
			((RadioButton)this.getWidget(row, column)).setValue(text.equals("true"), true);
			break;
		case GridColumn.column_Button:
		case GridColumn.column_image:
		case GridColumn.column_auto_number:
			break;
		case GridColumn.column_label_column:
			((Label)this.getWidget(row, column)).setText(text);
			break;
		case GridColumn.column_lookup_column:
			((TextBox)((HorizontalPanel)this.getWidget(row, column)).getWidget(0)).setText(text);
			break;
		}
	}
	
	public void setValues(int row, String[] values)
	{
		for (int i = 0; i < values.length; i++) {
			switch (gridColumns.get(i).columnType) {
			case GridColumn.column_default:
				this.setText(row, i, values[i]);
				break;
			case GridColumn.column_TextBox:
			case GridColumn.column_datebox:
				((TextBox)this.getWidget(row, i)).setText(values[i]);
				break;
			case GridColumn.column_ComboBox:
				ListBox l_lst = (ListBox)this.getWidget(row, i);
				for (int j = 0; j < l_lst.getItemCount(); j++) {
					if(values[i].equals(l_lst.getValue(j)))
					{
						l_lst.setSelectedIndex(j);
						break;
					}
				}
				break;
			case GridColumn.column_CheckBox:
				((CheckBox)this.getWidget(row, i)).setValue(values[i].equals("true"), true);
				break;
			case GridColumn.column_radio_button:
				((RadioButton)this.getWidget(row, i)).setValue(values[i].equals("true"), true);
				break;
			case GridColumn.column_Button:
			case GridColumn.column_image:
			case GridColumn.column_auto_number:
				break;
			case GridColumn.column_label_column:
				((Label)this.getWidget(row, i)).setText(values[i]);
				break;
			case GridColumn.column_lookup_column:
				((TextBox)((HorizontalPanel)this.getWidget(row, i)).getWidget(0)).setText(values[i]);
				break;
			}
		}
	}

	@Override
	public void onContextMenu(ContextMenuEvent event) {
		//event.preventDefault();
	    //event.stopPropagation();
	}
}
